<?php

/**
 * 安心站长axzz.cn，一个追求技术创造者。让网站、小程序、APP、应用程序牛起来……
 * 
 * cighsen02 qq 365182575
 * 
 * Create at：2022.10.26
 * Update at: 2025.09.16
 */

namespace Twoir\System\Support;

use function array_filter;
use function array_intersect;
use function array_replace;
use function implode;
use function is_array;
use function is_string;
use function sprintf;

/**
 * 单个表处理方式 集合方法
 */
trait SingleTrait
{
    /**
     * 字段默认值类型
     *
     * @return array
     */
    public static function fieldType(): array
    {
        $default = static::MYDEFAULT;

        // 字段类型
        foreach($default as &$value) {

            $value = null === $value || 0 === $value ? 'int' : 'string';
        }

        return $default;
    }

    /**
     * 数量统计
     * @param array $where
     * @return int
     */
    public static function getCount(array $where = []): int
    {
        global $empire, $dbtbpre;

        list($str_where) = static::parseWhere($where);

        $sql = sprintf('SELECT count(*) as total FROM %s%s', $dbtbpre . static::TABLE, $str_where);

        // 是否有记录
        return (int)$empire->gettotal($sql);
    }

    /**
     * 分组数量统计
     * 
     * @param array $where
     * @param string $group 分组关键字
     * @return int
     */
    public static function getGroupCount(array $where, string $group): array
    {
        global $empire, $dbtbpre;

        list($str_where) = static::parseWhere($where);

        $sql = sprintf('SELECT `' . $group . '`,count(`' . $group . '`) as total FROM `%s`%s%s', $dbtbpre . static::TABLE, $str_where, ' GROUP BY `' . $group . '`');

        $sql = $empire->query($sql);

        $res = [];

        if(0 < $empire->num1($sql)){

            while($r = $empire->fetch($sql)){
                // 去数字键
                $res[$r[$group]] = array_filter($r, fn($key) => is_string($key), ARRAY_FILTER_USE_KEY);
            }
        }

        return $res;
    }

    /**
     * 读取当条信息
     *
     * @param array $where = {key => val}, array $field = {item,item2}
     * @param array $field 调取的字段
     * @param string $orderby
     * @param string $groupby
     * @return array
     */
    public static function getOne(array $where = [], array $field = ['*'], string $groupby = '', string $orderby = ''): array
    {
        $result = static::getList($where, $field, $orderby, $groupby, 1, 0);

        return $result[0] ?? [];
    }

    /**
     * 读取多条(列表)
     *
     * @param array $where  条件
     * @param array $field 调取的字段
     * @param string $orderby
     * @param string $groupby
     * @param int $limit
     * @param int $pagesize
     * @param int $page
     * @return array
     */
    public static function getList(array $where = [], array $field = ['*'], string $groupby = '', string $orderby = '', int $limit = 0, int $pagesize = 10, int $page = 0): array
    {
        global $empire, $dbtbpre;

        list($str_where) = static::parseWhere($where);

        $get_field  = ['*'] === $field ? static::FIELD : array_intersect(static::FIELD, $field);

        $sql = sprintf('SELECT %s FROM `%s`%s%s%s%s',
            '`' . implode('`,`', $get_field) . '`',
            $dbtbpre . static::TABLE,
            $str_where,
            null === $groupby || '' === $groupby ? '' : ' GROUP BY ' . $groupby,
            null === $orderby || '' === $orderby ? '' : ' ORDER BY ' . $orderby,
            0 === $limit && 0 === $pagesize ? '' : ($limit > 0 ? ' LIMIT ' . $limit : ' LIMIT ' . ($page * $pagesize) . ',' . $pagesize)
        );

        $sql = $empire->query($sql);
        $result = [];

        if(0 < $empire->num1($sql)){

            while($r = $empire->fetch($sql)){
                // 去数字键
                $result[] = array_filter($r, fn($key) => is_string($key), ARRAY_FILTER_USE_KEY);
            }
        }

        return $result;
    }


    /**
     * 插入交易信息
     *
     * @param array $add
     * @return int|true 失败0 成功返回id，无主键时成功返回 true
     */
    public static function insert(array $add = []): int|bool
    {
        global $empire, $dbtbpre;

        if (empty($add) || !is_array($add)) return 0;

        // 过滤无关参数 0不过虑，所有没有 empty
        $add    = array_filter($add, fn($value, $key) => in_array($key, static::FIELD) && (null !== $value || '' !== $value), ARRAY_FILTER_USE_BOTH);
        // 更新值
        $add    = array_replace(static::MYDEFAULT, $add);
        list($str_key, $str_value) = static::parseInsert($add);

        $str_sql= sprintf('INSERT %sINTO `%s` (%s) VALUES (%s)',
            static::$low_priority ? 'LOW_PRIORITY ' : '',
            $dbtbpre . static::TABLE,
            $str_key,
            $str_value
        );

        $result	= $empire->query($str_sql);

        return $result ? (static::PRIMARY ? $empire->lastid() : true) : 0;
    }

    /**
     * 更新数据
     *
     * @param array $where
     * @param array $add
     * @param int $limit
     * @return bool
     */
    public static function update(array $where = [], array $add = [], int $limit = 0): bool
    {
        global $empire, $dbtbpre;

        list($str_where) = static::parseWhere($where);

        // 去null值, 0值或负值不能去，
        $add    = array_filter($add, fn($item) => null !== $item);
        // 找出要新字段进行更新
        $update = array_intersect(static::FIELD, array_keys($add));

        $update_data = array_filter($add, fn($item) => in_array($item, $update), ARRAY_FILTER_USE_KEY);

        $sql = sprintf('UPDATE %s`%s` SET %s%s%s',
            static::$low_priority ? 'LOW_PRIORITY ' : '',
            $dbtbpre . static::TABLE,
            static::parseUpdate($update_data),
            $str_where,
            $limit > 0 ? ' LIMIT ' . $limit : ''
        );

        return $empire->query($sql);
    }

    /**
     * 删除数据
     *
     * @param array $where
     * @param int $limit
     * @param string $orderby
     * @return bool
     */
    public static function delete(array $where = [], int $limit = 0, string $orderby = ''): bool
    {
        global $empire, $dbtbpre;

        list($str_where) = static::parseWhere($where);

        $sql = sprintf('DELETE %sFROM `%s`%s%s%s',
            static::$low_priority ? 'LOW_PRIORITY ' : '',
            $dbtbpre . static::TABLE,
            $str_where,
            null === $orderby || '' === $orderby ? '' : ' ORDER BY ' . $orderby,
            $limit > 0 ? ' limit ' . $limit : ''
        );

        return false !== $empire->query($sql);
    }
}
